%%%-------------------------------------------------------------------
%%% File    : gate_server.erl
%%% Author  :  <>
%%% Description : 
%%%
%%% Created : 16 Mar 2011 by  <>
%%%-------------------------------------------------------------------
-module(cache_server).

-behaviour(gen_server).

-export([start/1, start_link/1]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
	terminate/2, code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {sup,
		cache}).

%%--------
start(Sup) ->
    gen_server:start({global, ?SERVER}, ?MODULE, [Sup], []).

start_link(Sup) ->
    gen_server:start_link({global, ?SERVER}, ?MODULE, [Sup], []).
%%---------
init([Sup]) ->
    process_flag(trap_exit, true),
    S = #state{sup=Sup,
	       cache=ets:new(cache, [private, set, {keypos, 1}])},
    {ok, S}.


handle_call(_Rq, _From, S) ->
    {reply, ok, S}.


handle_cast(redirect, S) ->
    redirect(S);

handle_cast({do_exit, Pid}, S=#state{sup=Sup}) ->
    case Pid =:= Sup of
	true ->
	    {stop, normal, S};
	false ->
	    {noreply, S}
    end;

handle_cast(_Msg, S) ->
    {noreply, S}.

handle_info({'EXIT', _, normal}, S) ->
    {noreply, S};

handle_info({'EXIT', Pid, shutdown}, S=#state{sup=Sup}) ->
    case Pid =:= Sup of
	true ->
	    {stop, shutdown, S};
	false ->
	    {noreply, S}
    end;

handle_info({'EXIT', Pid, _Reason}, S=#state{sup=Sup}) ->
    case Pid of
	Sup ->
	    redirect(S);
	_Othes ->
	    {noreply, S}
    end;
    
handle_info(_Info, S) ->
    {noreply, S}.

terminate(_Reason, #state{cache=Cache}) ->
    ets:delete(Cache),
    ok.

code_change(_Oldvsn, S, _Extra) ->
    {ok, S}.

%%--------internal

redirect(S) ->
    case global:whereis_name(cache_sup) of
	Pid when is_pid(Pid) ->
	    link(Pid),
	    gen_server:cast(Pid, {redirect, node(), self()}),
	    {noreply, S#state{sup=Pid}};
	undefined ->
	    gen_server:cast(self(), redirect),
	    {noreply, S}
    end.


